package com.yuke.cloud.service.pmc.service.impl;

import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.RedisKeyUtil;
import com.yuke.cloud.service.api.cmc.dto.CmsSecKillDto;
import com.yuke.cloud.service.api.cmc.dto.CmsSecKillSkuDto;
import com.yuke.cloud.service.api.pmc.dto.ProdCategoryDto;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecApiDto;
import com.yuke.cloud.service.api.smc.service.SmcFeignApi;
import com.yuke.cloud.service.api.wmc.dto.StorageSpecInfoDto;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.pmc.dao.ProdCategoryMapper;
import com.yuke.cloud.service.pmc.dto.CategoryDto;
import com.yuke.cloud.service.pmc.dto.ProdBrandCategoryDto;
import com.yuke.cloud.service.pmc.dto.ProdCategoryBrandDto;
import com.yuke.cloud.service.pmc.dto.SecKillSkuInfoDto;
import com.yuke.cloud.service.pmc.entity.ProdBrand;
import com.yuke.cloud.service.pmc.entity.ProdCategory;
import com.yuke.cloud.service.pmc.entity.ProdSpec;
import com.yuke.cloud.service.pmc.service.DicRegionService;
import com.yuke.cloud.service.pmc.service.ProdBrandService;
import com.yuke.cloud.service.pmc.service.ProdCategoryService;
import com.yuke.cloud.service.pmc.service.ProdSpecService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * Created by zys on 2018/09/28.
 */
@Slf4j
@Service
@Transactional
public class ProdCategoryServiceImpl extends BaseService<ProdCategory> implements ProdCategoryService {
    @Resource
    private ProdCategoryMapper prodCategoryMapper;
    @Resource
    private ProdSpecService prodSpecService;
    @Resource
    private ProdBrandService prodBrandService;
    @Resource
    private DicRegionService dicRegionService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Resource
    private WmcStorageFeignApi wmcStorageFeignApi;

    @Resource
    private SmcFeignApi smcFeignApi;

    @Override
    public int save(ProdCategory record) {
        record.setCategoryId(generateId());
        record.setIsLeaf(true);
        if (null != record.getParentId() || "".equals(record.getParentId())) {
            ProdCategory prodCategory = new ProdCategory();
            prodCategory.setCategoryId(record.getParentId());
            //默认isLeaf是true
            prodCategory.setIsLeaf(false);
            update(prodCategory);
        }
        return super.save(record);
    }

    @Override
    public List<Long> getSubCategorysByParent(Long parentCategoryId) {
        return prodCategoryMapper.getSubCategorysByParent(parentCategoryId);
    }

    @Override
    public ProdCategoryDto getCategoryBySpecId(Long specId) {
        return prodCategoryMapper.getCategoryBySpecId(specId);
    }

    @Override
    public List<ProdCategoryDto> getCategorysBySpecId(Long specId) {
        List<ProdCategoryDto> prodCategoryDtos = new ArrayList<>();
        ProdCategoryDto prodCategoryDto = this.getCategoryBySpecId(specId);
        prodCategoryDtos.add(prodCategoryDto);
        //目前设定只有两级分类
        prodCategoryDtos.add(prodCategoryMapper.getCategoryByCategoryId(prodCategoryDto.getParentId()));
        return prodCategoryDtos;
    }

    @Override
    public List<ProdCategoryDto> getCategorysBySpecIds(List<Long> specIds) {
        List<ProdCategoryDto> prodCategoryDtos = prodCategoryMapper.getCategorysBySpecIds(specIds);
        prodCategoryDtos.addAll(prodCategoryMapper.getParentCategoryByCategoryIds(prodCategoryDtos.stream().map(prodCategoryDto -> prodCategoryDto.getParentId()).collect(Collectors.toList())));
        return prodCategoryDtos;
    }

    @Override
    public void parentCategoryId(Long categoryId, List<Long> categoryIds) {
        ProdCategory prodCategory = prodCategoryMapper.selectByPrimaryKey(categoryId);
        if (prodCategory == null) {
            return;
        }
        if (prodCategory.getParentId() != 0) {
            categoryIds.add(prodCategory.getParentId());
            parentCategoryId(prodCategory.getParentId(), categoryIds);
        }
    }

    @Override
    public List<ProdCategoryBrandDto> getProdCategoryBrand(ProdCategoryBrandDto prodCategoryBrandDto,Long shopId) {
        // add by wg 20190611 对排序方式进行判断

        if (prodCategoryBrandDto != null && prodCategoryBrandDto.getSortPriceType() != null) {
            String sortPriceType = prodCategoryBrandDto.getSortPriceType();
            if (!sortPriceType.equalsIgnoreCase("asc") && !sortPriceType.equalsIgnoreCase("desc")) {
                return new ArrayList<>();
            }
        }
        if (prodCategoryBrandDto != null && prodCategoryBrandDto.getSortCountType() != null) {
            String sorCountType = prodCategoryBrandDto.getSortCountType();
            if (!sorCountType.equalsIgnoreCase("asc") && !sorCountType.equalsIgnoreCase("desc")) {
                return new ArrayList<>();
            }
        }
        List<ProdCategoryBrandDto> prodCategoryBrand = new ArrayList<>();

        //todo 有类ID查询时，不要specName模糊查询
        if (prodCategoryBrandDto.getCategoryId() != null && prodCategoryBrandDto.getSpecName() != null){
           prodCategoryBrandDto.setSpecName("");
        }

        prodCategoryBrand = prodCategoryMapper.getProdCategoryBrand(prodCategoryBrandDto);

        //获取商品库存以及商品所在城市Id以及城市名称和所属仓库  判断商品是否为秒杀价格
        //todo
        getInfo(prodCategoryBrand,prodCategoryBrandDto.getSaleType(),shopId);

        if (prodCategoryBrandDto.getSaleType() !=null &&!prodCategoryBrandDto.getSaleType().toString().equals("2")){
            if (prodCategoryBrandDto.getSortPriceType() == null&& prodCategoryBrandDto.getSortCountType()==null){
                prodCategoryBrand.sort(Comparator.comparing
                        (ProdCategoryBrandDto::getCreateTime).reversed());
            }

            return prodCategoryBrand;
        }else {
            List<ProdCategoryBrandDto> collect = new ArrayList<>();
            //collect = prodCategoryBrand.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ProdCategoryBrandDto::getSpecId))), ArrayList::new));
            if (prodCategoryBrand !=null && prodCategoryBrand .size()>0 && prodCategoryBrandDto.getSortPriceType() == null
                    && prodCategoryBrandDto.getSortCountType() == null){
                collect=prodCategoryBrand.stream().collect(
                        Collectors.collectingAndThen(
                                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ProdCategoryBrandDto::getProductId))), ArrayList::new)
                );
                //按创建时间排序
                collect.sort(Comparator.comparing(ProdCategoryBrandDto::getCreateTime).reversed());
            }

            if (prodCategoryBrandDto.getSortPriceType() != null) {
                String sortPriceType = prodCategoryBrandDto.getSortPriceType();
                if (sortPriceType.equalsIgnoreCase("asc")) {
                    collect.sort(Comparator.comparing(ProdCategoryBrandDto::getMarketPrice));
                } else if (sortPriceType.equalsIgnoreCase("desc")) {
                    collect.sort(Comparator.comparing(ProdCategoryBrandDto::getMarketPrice).reversed());
                }
            }
            if (prodCategoryBrandDto.getSortCountType() != null) {
                String sortCountType = prodCategoryBrandDto.getSortCountType();
                if (sortCountType.equalsIgnoreCase("asc")) {
                    collect.sort(Comparator.comparing(ProdCategoryBrandDto::getSaleCount));
                } else if (sortCountType.equalsIgnoreCase("desc")) {
                    collect.sort(Comparator.comparing(ProdCategoryBrandDto::getSaleCount).reversed());
                }
            }
            return collect;
        }

    }

    @Override
    public List<ProdBrandCategoryDto> getFilter(ProdCategoryBrandDto prodCategoryBrandDto) {
        List<ProdBrandCategoryDto> prodBrandCategoryDtos = new ArrayList<>();
        ProdBrandCategoryDto ps = new ProdBrandCategoryDto();
        if (prodCategoryBrandDto != null) {
            //通过品牌ID找分类
            if (prodCategoryBrandDto.getBrandId() != null && !prodCategoryBrandDto.getBrandId().toString().equals(' ')) {
                List<ProdCategory> categorys = prodBrandService.getCategory(prodCategoryBrandDto.getBrandId());
                ps.setProdCategories(categorys);
                prodBrandCategoryDtos.add(ps);
            }
            //通过分类ID找品牌
            if (prodCategoryBrandDto.getCategoryId() != null) {
                List<ProdBrand> brandByCategoryIds = prodBrandService.getBrandByCategoryIds(prodCategoryBrandDto.getCategoryId());

                ps.setProdBrands(brandByCategoryIds);
                prodBrandCategoryDtos.add(ps);
            }
        }

        return prodBrandCategoryDtos;
    }


    @Override
    public  List<ProdCategory>  getFindAllCategory() {
        Example example = new Example(ProdCategory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",GlobalConstant.PMC_CATEGORY);
        List<ProdCategory> prodCategories = selectByExample(example);
        return prodCategories;
    }

    @Override
    public List<ProdCategoryBrandDto> getProdBrandCategory(ProdCategoryBrandDto prodCategoryBrandDto, Long shopId) {

       List<ProdCategoryBrandDto> prodCategoryBrand  = prodCategoryMapper.getProdBrandCategory(prodCategoryBrandDto);

        //获取商品库存以及商品所在城市Id以及城市名称和所属仓库  判断商品是否为秒杀价格
        getInfo(prodCategoryBrand,prodCategoryBrandDto.getSaleType(),shopId);

        return  prodCategoryBrand;
    }

    @Override
    public List<CategoryDto> getFindCategory(Byte categoryType) {
        List<CategoryDto> findAllCategory = prodCategoryMapper.getFindCategory(categoryType);
        return  findAllCategory;
    }


    @Override
    public int isEnable(Long categoryId, Integer isEnable) {
        List<Long> ids = new ArrayList<>();
        this.subCategoryId(categoryId, ids);
        if (isEnable == 0) {
            //禁用
            //如果该分类下有商品（有未禁用的商品），则无法禁用
            List<ProdSpec> prodSpecs = prodSpecService.getEnableSpecByCategoryIds(ids);
            if (prodSpecs.size() > 0) {
                return 0;
            }
        } else {
            //启用
            if (ids.size() == 1) {
                //子分类启用，若父分类禁用，则父分类同时启用
                ProdCategory prodCategory = prodCategoryMapper.selectByPrimaryKey(ids.get(0));
                ids.add(prodCategory.getParentId());
            }
        }
        return prodCategoryMapper.isEnable(ids, isEnable);
    }

    @Override
    public List<CategoryDto> findAllEnableList(Byte saleType) {
           return prodCategoryMapper.findAllEnableList(saleType);
    }

    @Override
    public List<CategoryDto> findAllList() {
        return prodCategoryMapper.findAllList();
    }

    @Override
    public CategoryDto findInfoById(Long id) {
        return prodCategoryMapper.findInfoById(id);
    }

    /**
     * 获取所有的子节点
     *
     * @param categoryId
     * @param categoryIds
     */
    @Override
    public void subCategoryId(Long categoryId, List<Long> categoryIds) {
        ProdCategory prodCategory = prodCategoryMapper.selectByPrimaryKey(categoryId);
        if (prodCategory == null) {
            return;
        }
        if (prodCategory.getIsLeaf()) {
            categoryIds.add(prodCategory.getCategoryId());
        } else {
            categoryIds.add(categoryId);
            List<Long> subCategoryIds = this.getSubCategorysByParent(categoryId);
            for (Long id : subCategoryIds) {
                this.subCategoryId(id, categoryIds);
            }
        }
    }

    /**
     * 获取所有的叶子节点
     *
     * @param categoryId
     * @param categoryIds
     */
    @Override
    public void leafCategoryId(Long categoryId, List<Long> categoryIds) {
        ProdCategory prodCategory = prodCategoryMapper.selectByPrimaryKey(categoryId);
        if (prodCategory == null) {
            return;
        }
        if (prodCategory.getIsLeaf()) {
            categoryIds.add(prodCategory.getCategoryId());
        } else {
            List<Long> subCategoryIds = this.getSubCategorysByParent(categoryId);
            for (Long id : subCategoryIds) {
                this.leafCategoryId(id, categoryIds);
            }
        }
    }


    private void  getInfo(List<ProdCategoryBrandDto> prodCategoryBrands ,Byte saleType,Long shopId ) {

        List<Long> specIds = new ArrayList<>();
        specIds = prodCategoryBrands.stream().map(ProdCategoryBrandDto::getSpecId).collect(Collectors.toList());
        if (specIds.size() > 0) {

            List<StorageSpecInfoDto> storageSpecInfoDtoList =wmcStorageFeignApi.getWmsSpecInfoBySpecIds(specIds,shopId);

            if (storageSpecInfoDtoList != null && storageSpecInfoDtoList.size()>0){
                for(ProdCategoryBrandDto item : prodCategoryBrands ){
                    boolean flag = true;
                    for(StorageSpecInfoDto spec : storageSpecInfoDtoList){

                        if (item.getSpecId().equals(spec.getSpecId())){
                            item.setMarketPrice(spec.getMarketPrice());
                            item.setRegionCityId(spec.getWareCityId());
                            item.setWarehouseId(spec.getWarehouseId());
                            item.setStorageId(spec.getStorageId());
                            item.setSaleCount(spec.getSaleCount());

                            if (spec.getNumber()-spec.getLockNumber() >= 0){
                                item.setStockCount(spec.getNumber()-spec.getLockNumber());
                            }else{
                                item.setStockCount(0);
                            }

                            //todo 20191214 bigPic 赋值给smallPic
                            item.setSmallPicUri(item.getBigPicUri());
                            //todo 20191114 如果有秒杀商品，把秒杀商品的价格统一为商家端销售价
                            //空不等于是否为秒杀活动商品
                            if (null != item.getIsSecKill()){
                                //秒杀商品是否为true
                                if (item.getIsSecKill()){
                                    //将秒杀价格设置为B端商品价格
                                    if (item.getSaleType().toString().equals("1")){
                                        item.setSecKillPrice(spec.getMarketPrice());
                                    }else {
                                        item.setSecKillPrice(spec.getSalePrice());
                                    }

                                }
                            }
                            flag = false;
                            break;
                        }

                    }
                    if(flag){
                        storageSpecInfoDtoList.remove(item);
                    }

                }
            }
        }

        if (saleType != null && saleType.equals((byte) 2)) {
            List<SecKillSkuInfoDto> secKillSkus = getSecKillSkus();
            for (ProdCategoryBrandDto categoryBrandDto : prodCategoryBrands) {
                for (SecKillSkuInfoDto killSkus : secKillSkus) {

                    if (killSkus.getCmsSecKillSkuDto().getSpecId().longValue() == categoryBrandDto.getSpecId().longValue()) {
                        if ((killSkus.getCmsSecKillSkuDto().getStoreCount() - killSkus.getCmsSecKillSkuDto().getLockCount()) > 0) {
                            categoryBrandDto.setIsSecKill(true);
                            categoryBrandDto.setSecKillPrice(killSkus.getCmsSecKillSkuDto().getSecKillPrice());
                            categoryBrandDto.setSecKillEndTime(killSkus.getSecKillEndTime());
                        }
                    }
                }
            }
        }
    }


    @Override
    public  List<ProdCategory>  findAppCategoryOneLevel(Byte saleType) {
        System.out.println("AAAAAAAAAAAAA"+ saleType);
        Example example = new Example(ProdCategory.class);
        Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("sort");
        criteria.andEqualTo("parentId",0L);
        criteria.andEqualTo("isEnable",(byte)1);
        if (saleType.equals((byte)1)){
            criteria.andCondition("client_view = 1 ");
        }else{
            //criteria.andCondition("category_type = 1 ");
            criteria.andCondition("business_view = 1");
        }
        List<ProdCategory> prodCategories = selectByExample(example);
        System.out.println("一级分类="+ prodCategories);
        return prodCategories;
    }

    @Override
    public  List<ProdCategory>  findAppCategoryTwoLevel(Long categoryId,String tag) {

        Example example = new Example(ProdCategory.class);
        Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("sort");
        criteria.andEqualTo("parentId",categoryId);
        criteria.andEqualTo("isEnable",(byte)1);
        if ("B".equals(tag)){
            criteria.andEqualTo("businessView",(byte)1);
        }else{
            criteria.andEqualTo("clientView",(byte)1);
        }

        List<ProdCategory> prodCategories = selectByExample(example);
        return prodCategories;
    }

    @Override
    public  List<Long> findLeaf(ProdCategoryDto prodCategoryDto) {
        Example example = new Example(ProdCategory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",prodCategoryDto.getParentId());
        List<ProdCategory> prodCategories = prodCategoryMapper.selectByExample(example);
        List<Long> collect = prodCategories.stream().map(ProdCategory::getCategoryId).collect(Collectors.toList());
        return collect;
    }

    // 获取正在秒杀活动中的商品
    private List<SecKillSkuInfoDto> getSecKillSkus() {
        Set<String> keys = redisTemplate.keys(RedisKeyUtil.getSecKillKeys());

        if (CollectionUtils.isEmpty(keys)) {
            return new ArrayList<>();
        }

        List<SecKillSkuInfoDto> secKillSkuInfoDtoList = new ArrayList<>();
        Date now = new Date();
        for (String secKillKey : keys) {
            CmsSecKillDto cmsSecKillDto = (CmsSecKillDto) redisTemplate.opsForValue().get(secKillKey);
            if (cmsSecKillDto != null && cmsSecKillDto.getIsEnable() && now.getTime() >= cmsSecKillDto.getStartTime().getTime()
                    && now.getTime() <= cmsSecKillDto.getEndTime().getTime()) {
                Set<String> skuKeys = redisTemplate.keys(RedisKeyUtil.getSecKillSkuKeys(String.valueOf(cmsSecKillDto.getSecKillId())));

                for (String skuKey : skuKeys) {
                    CmsSecKillSkuDto cmsSecKillSkuDto = (CmsSecKillSkuDto) redisTemplate.opsForValue().get(skuKey);
                    SecKillSkuInfoDto secKillSkuInfoDto = new SecKillSkuInfoDto();
                    secKillSkuInfoDto.setCmsSecKillSkuDto(cmsSecKillSkuDto);
                    secKillSkuInfoDto.setSecKillEndTime(cmsSecKillDto.getEndTime());
                    if (cmsSecKillSkuDto != null) {
                        secKillSkuInfoDtoList.add(secKillSkuInfoDto);
                    }
                }
            }
        }

        return secKillSkuInfoDtoList;
    }

    //12/10
    @Override
    public List<ProdSpecApiDto> findParent(List<Long> list) {
        List<ProdSpecApiDto> result = prodCategoryMapper.findParent(list);
        return result;
    }


    @Override
    public  List<ProdCategory>  findCategoryByClassId(Long classId,String tag) {

        Example example = new Example(ProdCategory.class);
        Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("sort");
        criteria.andEqualTo("classId",classId);
        criteria.andEqualTo("isEnable",(byte)1);
        if ("B".equals(tag)){
            criteria.andEqualTo("businessView",(byte)1);
        }else{
            criteria.andEqualTo("clientView",(byte)1);
        }

        List<ProdCategory> prodCategories = selectByExample(example);
        return prodCategories;
    }
}
